package com.souche.employment.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.souche.employment.CommonUtils;
import com.souche.employment.domain.EmployeeDO;
import com.souche.employment.domain.JobDO;
import com.souche.employment.dto.EmployeeDto;
import com.souche.employment.es.dao.PersonSearchRepository;
import com.souche.employment.es.domain.PersonSearchDO;
import com.souche.employment.interceptor.AuthHolder;
import com.souche.employment.mapper.EmployeeMapper;
import com.souche.employment.mapper.JobMapper;
import com.souche.employment.response.CustomException;
import com.souche.employment.response.DataResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * BaseController.java created at 2017年8月8日 下午1:11:20
 *
 * @author Ray [email:rayinhangzhou@hotmail.com] Revision History Date Programmer Notes
 * ----------------------------------------------------------
 **/
@Slf4j
@RestController
@RequestMapping(value = "/employ")
@Api(value = "/employ", description = "简历相关接口")
public class EmployController {
    @Value("${file.upload-path}")
    private String filePath;
    @Value("${file.size-limit}")
    private long fileSize;

    @Autowired
    private JobMapper jobMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private PersonSearchRepository personSearchRepository;


    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @ApiOperation(value = "搜索人员")
    public DataResult search(
            @ApiParam(value = "关键字") @RequestParam(required = false) String key,
            @ApiParam(value = "邀约状态") @RequestParam(required = false) String inviteStatus,
            @ApiParam(value = "面试进度") @RequestParam(required = false) String interviewStatus,
            @ApiParam(value = "处理状态") @RequestParam(required = false) String dealStatus,
            @ApiParam(value = "一级部门") @RequestParam(required = false) String dep1,
            @ApiParam(value = "二级部门") @RequestParam(required = false) String dep2,
            @ApiParam(value = "入职时间") @RequestParam(required = false) String entryDate0,
            @ApiParam(value = "入职时间") @RequestParam(required = false) String entryDate1,
            @RequestParam int pageNum,
            @RequestParam int pageSize,
            @RequestParam String sortName,
            @RequestParam String sortOrder) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
                .withPageable(new PageRequest(pageNum - 1, pageSize));
        FieldSortBuilder sortBuilder = SortBuilders.fieldSort(sortName);
        if ("asc".equalsIgnoreCase(sortOrder)) {
            sortBuilder.order(SortOrder.ASC);
        } else {
            sortBuilder.order(SortOrder.DESC);
        }
        queryBuilder.withSort(sortBuilder);
        if (StringUtils.isNotBlank(key)) {
            queryBuilder.withQuery(QueryBuilders.matchQuery("key", key));
        }
        if (StringUtils.isNotBlank(inviteStatus)) {
            queryBuilder.withFilter(QueryBuilders.termQuery("inviteStatus", inviteStatus));
        }
        if (StringUtils.isNotBlank(interviewStatus)) {
            queryBuilder.withFilter(QueryBuilders.termQuery("interviewStatus", interviewStatus));
        }
        if (StringUtils.isNotBlank(dep1)) {
            queryBuilder.withFilter(QueryBuilders.termQuery("dep1", dep1));
        }
        if (StringUtils.isNotBlank(interviewStatus)) {
            queryBuilder.withFilter(QueryBuilders.termQuery("dep2", dep2));
        }
        if ("doing".equalsIgnoreCase(dealStatus)) {
            queryBuilder.withFilter(QueryBuilders.termsQuery("interviewStatus", "未参加面试", "初试通过", "复试通过"));
        }
        if ("done".equalsIgnoreCase(dealStatus)) {
            queryBuilder.withFilter(QueryBuilders.termsQuery("interviewStatus", "淘汰", "储备", "已入职", "已离职", "录用"));
        }
        if (StringUtils.isNotBlank(entryDate0)) {
            long stamp = CommonUtils.parseDate(entryDate0, "yyyy-MM-dd").getTime();
            queryBuilder.withFilter(QueryBuilders.rangeQuery("entryDate").gte(stamp));
        }
        if (StringUtils.isNotBlank(entryDate1)) {
            long stamp = CommonUtils.parseDate(entryDate1, "yyyy-MM-dd").getTime();
            queryBuilder.withFilter(QueryBuilders.rangeQuery("entryDate").lt(stamp));
        }
        Page<PersonSearchDO> page = elasticsearchTemplate.queryForPage(queryBuilder.build(), PersonSearchDO.class);
        List<EmployeeDto> result = new ArrayList<>();
        if (page.getContent()!=null) {
            page.getContent().stream().forEach(PersonSearchDO -> result.add(new EmployeeDto(PersonSearchDO)));
        }
        PageInfo<EmployeeDto> pageInfo = new PageInfo<>(result);
        pageInfo.setTotal(page.getTotalElements());
        pageInfo.setSize(page.getNumberOfElements());
        return DataResult.success(pageInfo);
    }

    @RequestMapping(value="/interviewList", method=RequestMethod.GET)
    @ApiOperation(value="约面列表")
    public DataResult interviewList(
            @ApiParam(value = "HR") @RequestParam(required = false) String hr,
            @ApiParam(value = "一级部门") @RequestParam(required = false) String dep1,
            @ApiParam(value = "二级部门") @RequestParam(required = false) String dep2,
            @ApiParam(value = "约面时间") @RequestParam(required = false) String interviewTime0,
            @ApiParam(value = "约面时间") @RequestParam(required = false) String interviewTime1,
            @RequestParam int pageNum,
            @RequestParam int pageSize,
            @RequestParam(required = false) String sort) {
        sort = StringUtils.isBlank(sort)?"interviewTime asc":sort;
        PageHelper.startPage(pageNum, pageSize);
        List<EmployeeDO> list = employeeMapper.getListForInterview(hr, dep1, dep2,
                CommonUtils.parseDate(interviewTime0, "yyyy-MM-dd HH:mm"),
                CommonUtils.parseDate(interviewTime1, "yyyy-MM-dd HH:mm"), sort);
        List<EmployeeDto> result = new ArrayList<>();
        if (list!=null) {
            list.stream().forEach(item -> result.add(new EmployeeDto(item)));
        }
        PageInfo<EmployeeDto> pageInfo = new PageInfo<>(result);
        return DataResult.success(pageInfo);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加简历")
    public DataResult add(
            @ApiParam(value = "姓名", required = true) @RequestParam String name,
            @ApiParam(value = "性别：先生|女士", required = true) @RequestParam String gender,
            @ApiParam(value = "年龄", required = true) @RequestParam Integer age,
            @ApiParam(value = "工作年限", required = true) @RequestParam Integer workAge,
            @ApiParam(value = "联系方式", required = true) @RequestParam String phone,
            @ApiParam(value = "邮箱", required = true) @RequestParam String mail,
            @ApiParam(value = "简历获取方式：投递|搜索|内推|外推", required = true) @RequestParam String pipe,
            @ApiParam(value = "简历来源，标签", required = true) @RequestParam String referee,
            @ApiParam(value = "推荐人") @RequestParam(required = false) String sender,
            @ApiParam(value = "备注标签") @RequestParam(required = false) String tips,
            @ApiParam(value = "职位id", required = true) @RequestParam String jobId,
            @ApiParam(value = "职位名称", required = true) @RequestParam String jobName,
            @ApiParam(value = "邀请进度：未接听|待答复|已约面|拒绝邀约", required = true) @RequestParam String inviteStatus,
            @ApiParam(value = "面试进度：未参加面试|初试通过|复试通过|录用|淘汰|储备|已入职|已离职", required = true) @RequestParam String interviewStatus,
            @ApiParam(value = "约面时间") @RequestParam(required = false) String interviewTime,
            @ApiParam(value = "面试方式，标签") @RequestParam(required = false) String interviewType,
            @ApiParam(value = "一面面试官") @RequestParam(required = false) String interviewer1,
            @ApiParam(value = "二面面试官") @RequestParam(required = false) String interviewer2,
            @ApiParam(value = "HR面试官") @RequestParam(required = false) String interviewer0,
            @ApiParam(value = "文件地址") @RequestParam(required = false) String fileUrl) {
        JobDO job = jobMapper.getJob(jobId);
        if (job == null) {
            throw CustomException.fail("该职位不存在！", null);
        }
        EmployeeDO employeeDO = new EmployeeDO();
        employeeDO.setId(CommonUtils.getShortUuid());
        employeeDO.setName(name);
        employeeDO.setAge(age);
        employeeDO.setWorkAge(workAge);
        employeeDO.setGender(gender);
        employeeDO.setPhone(phone);
        employeeDO.setMail(mail);
        employeeDO.setPipe(pipe);
        employeeDO.setReferee(referee);
        employeeDO.setSender(sender);
        employeeDO.setTips(tips);
        employeeDO.setJobId(jobId);
        employeeDO.setJobName(jobName);
        employeeDO.setDep1(job.getDep1());
        employeeDO.setDep2(job.getDep2());
        employeeDO.setInviteStatus(inviteStatus);
        employeeDO.setInterviewStatus(interviewStatus);
        employeeDO.setInterviewTime(CommonUtils.parseDate(interviewTime, "yyyy-MM-dd HH:mm"));
        employeeDO.setInterviewType(interviewType);
        employeeDO.setInterviewer0(interviewer0);
        employeeDO.setInterviewer1(interviewer1);
        employeeDO.setInterviewer2(interviewer2);
        employeeDO.setFile(fileUrl);
        employeeDO.setCreator(AuthHolder.mail());
        employeeMapper.add(employeeDO);
        // 更新数据到索引
        saveEmployee2Es(employeeDO);
        return DataResult.success(employeeDO);
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    @ResponseBody
    @ApiOperation(value = "上传文件")
    public String uploadAdFile(
            @RequestParam("employee_upload") MultipartFile file,
            @RequestParam String dir) {
        try {
            long fileSize = file.getSize();
            if (fileSize > fileSize) {
                return JSONObject.toJSONString(DataResult.fail("文件请控制在10M以内~", null));
            }
            String completePath = filePath + dir;
            if (!new File(completePath).exists()) {
                new File(completePath).mkdirs();
            }
            String fileName = CommonUtils.getShortUuid() + "_" + file.getOriginalFilename();
            file.transferTo(new File(completePath + "/" + fileName));
            return JSONObject.toJSONString(DataResult.success("/" + dir + "/" + fileName));
        } catch (Exception e) {
            log.error(AuthHolder.mail() + "-" + file.getOriginalFilename(), e);
            return JSONObject.toJSONString(DataResult.fail("上传异常", null));
        }
    }

    @RequestMapping(value = "/get", method = RequestMethod.GET)
    @ApiOperation(value = "获取简历")
    public DataResult get(
            @ApiParam(value = "id", required = true) @RequestParam String id) {
        EmployeeDO employeeDO = employeeMapper.get(id);
        return DataResult.success(employeeDO);
    }

    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    @ApiOperation(value = "获取简历详情")
    public DataResult detail(
            @ApiParam(value = "id", required = true) @RequestParam String id) {
        EmployeeDO employeeDO = employeeMapper.get(id);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(employeeDO));

        return DataResult.success(employeeDO);
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ApiOperation(value = "编辑简历")
    public DataResult edit(
            @ApiParam(value = "id", required = true) @RequestParam String id,
            @ApiParam(value = "姓名", required = true) @RequestParam String name,
            @ApiParam(value = "性别：先生|女士", required = true) @RequestParam String gender,
            @ApiParam(value = "年龄", required = true) @RequestParam Integer age,
            @ApiParam(value = "工作年限", required = true) @RequestParam Integer workAge,
            @ApiParam(value = "联系方式", required = true) @RequestParam String phone,
            @ApiParam(value = "邮箱", required = true) @RequestParam String mail,
            @ApiParam(value = "简历获取方式：投递|搜索|内推|外推", required = true) @RequestParam String pipe,
            @ApiParam(value = "简历来源，标签", required = true) @RequestParam String referee,
            @ApiParam(value = "推荐人") @RequestParam(required = false) String sender,
            @ApiParam(value = "备注标签") @RequestParam(required = false) String tips,
            @ApiParam(value = "职位id", required = true) @RequestParam String jobId,
            @ApiParam(value = "职位名称", required = true) @RequestParam String jobName,
            @ApiParam(value = "约面时间") @RequestParam(required = false) String interviewTime,
            @ApiParam(value = "面试方式，标签") @RequestParam(required = false) String interviewType,
            @ApiParam(value = "一面面试官") @RequestParam(required = false) String interviewer1,
            @ApiParam(value = "二面面试官") @RequestParam(required = false) String interviewer2,
            @ApiParam(value = "HR面试官") @RequestParam(required = false) String interviewer0) {
        JobDO job = jobMapper.getJob(jobId);
        if (job == null) {
            throw CustomException.fail("该职位不存在！", null);
        }
        EmployeeDO employeeDO = employeeMapper.get(id);
        if (employeeDO == null) {
            throw CustomException.fail("该简历不存在！", null);
        }
        employeeDO.setName(name);
        employeeDO.setAge(age);
        employeeDO.setWorkAge(workAge);
        employeeDO.setGender(gender);
        employeeDO.setPhone(phone);
        employeeDO.setMail(mail);
        employeeDO.setPipe(pipe);
        employeeDO.setReferee(referee);
        employeeDO.setSender(sender);
        employeeDO.setTips(tips);
        employeeDO.setJobId(jobId);
        employeeDO.setJobName(jobName);
        employeeDO.setDep1(job.getDep1());
        employeeDO.setDep2(job.getDep2());
        employeeDO.setInterviewTime(CommonUtils.parseDate(interviewTime, "yyyy-MM-dd HH:mm"));
        employeeDO.setInterviewType(interviewType);
        employeeDO.setInterviewer0(interviewer0);
        employeeDO.setInterviewer1(interviewer1);
        employeeDO.setInterviewer2(interviewer2);
        employeeDO.setCreator(AuthHolder.mail());
        employeeMapper.update(employeeDO);
        // 更新数据到索引
        saveEmployee2Es(employeeDO);
        return DataResult.success(new EmployeeDto(employeeDO));
    }

    @RequestMapping(value = "/updateInviteStatus", method = RequestMethod.POST)
    @ApiOperation(value = "更新邀约进度")
    public DataResult updateInviteStatus(
            @ApiParam(value = "id", required = true) @RequestParam String id,
            @ApiParam(value = "邀约进度", required = true) @RequestParam String inviteStatus,
            @ApiParam(value = "约面时间") @RequestParam(required = false) String interviewTime,
            @ApiParam(value = "面试方式") @RequestParam(required = false) String interviewType) {
        EmployeeDO employeeDO = employeeMapper.get(id);
        if (employeeDO == null) {
            throw CustomException.fail("该简历不存在！", null);
        }
        employeeDO.setInviteStatus(inviteStatus);
        if ("已约面".equals(inviteStatus)) {
            employeeDO.setInterviewTime(CommonUtils.parseDate(interviewTime, "yyyy-MM-dd HH:mm"));
            employeeDO.setInterviewType(interviewType);
        }
        employeeMapper.updateInviteStatus(employeeDO);
        // 更新数据到索引
        saveEmployee2Es(employeeDO);
        return DataResult.success(new EmployeeDto(employeeDO));
    }

    @RequestMapping(value = "/updateInterviewStatus", method = RequestMethod.POST)
    @ApiOperation(value = "更新面试进度")
    public DataResult updateInterviewStatus(
            @ApiParam(value = "id", required = true) @RequestParam String id,
            @ApiParam(value = "面试进度", required = true) @RequestParam String interviewStatus,
            @ApiParam(value = "面试人员") @RequestParam(required = false) String interviewer) {
        EmployeeDO employeeDO = employeeMapper.get(id);
        if (employeeDO == null) {
            throw CustomException.fail("该简历不存在！", null);
        }
        employeeDO.setInterviewStatus(interviewStatus);
        if (StringUtils.isNotBlank(interviewer)) {
            //TODO 发面试记录邮件
        }
        employeeMapper.updateInterviewStatus(employeeDO);
        // 更新数据到索引
        saveEmployee2Es(employeeDO);
        return DataResult.success(new EmployeeDto(employeeDO));
    }

    @RequestMapping(value = "/updateFile", method = RequestMethod.POST)
    @ApiOperation(value = "更新面试进度")
    public DataResult updateInterviewStatus(
            @ApiParam(value = "id", required = true) @RequestParam String id,
            @ApiParam(value = "简历地址", required = true) @RequestParam String fileUrl) {
        EmployeeDO employeeDO = employeeMapper.get(id);
        if (employeeDO == null) {
            throw CustomException.fail("该简历不存在！", null);
        }
        employeeDO.setFile(fileUrl);
        employeeMapper.updateFile(employeeDO);
        return DataResult.success(new EmployeeDto(employeeDO));
    }


    /**
     * 更新索引数据
     *
     * @param employeeDO
     */
    private void saveEmployee2Es(EmployeeDO employeeDO) {
        PersonSearchDO personSearchDO = new PersonSearchDO();
        personSearchDO.setId(employeeDO.getId());
        personSearchDO.setKey(employeeDO.getName() + "," + employeeDO.getPhone() + "," + employeeDO.getTips() + "," + employeeDO.getJobName());
        personSearchDO.setName(employeeDO.getName());
        personSearchDO.setPhone(employeeDO.getPhone());
        personSearchDO.setJobId(employeeDO.getJobId());
        personSearchDO.setJobName(employeeDO.getJobName());
        personSearchDO.setDep1(employeeDO.getDep1());
        personSearchDO.setDep2(employeeDO.getDep2());
        personSearchDO.setTip(employeeDO.getTips());
        personSearchDO.setInviteStatus(employeeDO.getInviteStatus());
        personSearchDO.setInterviewStatus(employeeDO.getInterviewStatus());
        personSearchDO.setDateEntry(0L);
        personSearchDO.setDateCreate(employeeDO.getDateCreate().getTime());
        personSearchRepository.save(personSearchDO);
    }

}
